package com.huilian.netty.config;


import com.huilian.netty.constant.CIMConstant;
import com.huilian.netty.handler.*;
import com.huilian.netty.model.CIMSession;
import com.huilian.netty.model.SocketMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.util.HashMap;

@Slf4j
@Configuration
public class CIMConfig implements CIMRequestHandler, ApplicationListener<ApplicationStartedEvent> {

    @Resource
    private ApplicationContext applicationContext;
    public final static HashMap<String, CIMRequestHandler> innerHandlerMap = new HashMap<>();

    @Bean(destroyMethod = "destroy")
    public CIMNioSocketAcceptor getNioSocketAcceptor(
            @Value("${cim.websocket.port}") int websocketPort) {

        return new CIMNioSocketAcceptor.Builder()
                .setWebsocketPort(websocketPort)
                .setOuterRequestHandler(this)
                .build();

    }

    @Override
    public void process(CIMSession session, SocketMessage socketMessage) {

        CIMRequestHandler handler = innerHandlerMap.get(socketMessage.getType());

        if (handler == null) {
            return;
        }

        handler.process(session, socketMessage);
    }

    /*
     * springboot启动完成之后再启动cim服务的，避免服务正在重启时，客户端会立即开始连接导致意外异常发生.
     */
    @Override
    public void onApplicationEvent(ApplicationStartedEvent applicationStartedEvent) {
        innerHandlerMap.put(CIMConstant.MessageType.CLIENT_CONNECT_CLOSED,applicationContext.getBean(SessionClosedHandler.class));
        innerHandlerMap.put(CIMConstant.MessageType.CLIENT_MESSAGE,applicationContext.getBean(MessageHandler.class));
        innerHandlerMap.put(CIMConstant.MessageType.CLIENT_HEARTBEAT, applicationContext.getBean(HeartbeatHandler.class));
        innerHandlerMap.put(CIMConstant.MessageType.CLIENT_BIND,applicationContext.getBean(BindHandler.class));
        applicationContext.getBean(CIMNioSocketAcceptor.class).bind();
    }
}
